home *** CD-ROM | disk | FTP | other *** search
- /*
- * getami.c - display a Utah RLE picture on a Commodore Amiga
- *
- * Authors: Eleftherios Koutsofios (ek@ulysses.att.com)
- * Kriton Kyrimis (kyrimis%theseas@csi.forth.gr)
- */
-
- #include <stdio.h>
- #include <intuition/intuition.h>
- #include <libraries/dos.h>
- #include <libraries/asl.h>
- #include <utility/tagitem.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/gfxbase.h>
- #include <graphics/view.h>
- #include <utility/tagitem.h>
- #ifndef NOIFFLIB
- #include <iff.h>
- #endif
- #include <rle.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #ifdef __SASC
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/asl.h>
- #endif
- #ifdef __GNUC__
- #include <inline/intuition.h>
- #include <inline/graphics.h>
- #include <inline/dos.h>
- #include <inline/exec.h>
- #include <inline/asl.h>
- #endif
-
- #ifdef __SASC
- extern void __asm MultiPlot(register __a0 struct Window *,
- register __d0 WORD,
- register __d1 WORD,
- register __d2 WORD);
- #else
- #ifdef __GNUC__
- static __inline void
- MP(struct Window *w, WORD x, WORD y, WORD c)
- {
- register struct Window *a0 __asm("a0") = w;
- register long d0 __asm("d0") = x;
- register long d1 __asm("d1") = y;
- register long d2 __asm("d2") = c;
- __asm __volatile ("jsr _MultiPlot"
- : /* no output */
- : "r" (a0), "r" (d0), "r" (d1), "r" (d2)
- : "a0", "a1", "d0", "d1", "d2", "memory");
- }
- #define MultiPlot MP
- #else
- #define NOASM
- #endif
- #endif
-
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
- #define ABS(x) ((x) >= 0 ? (x) : -(x))
- #define MAX(x,y) ((x) > (y) ? (x) : (y))
- #define cindex(r, g, b) ((((r) >> 4) << 8) | (((g) >> 4) << 4) | ((b) >> 4))
- #define rdist(a, b) \
- ((ABS (((cusage[a].i >> 8) & 0xf) - ((cusage[b].i >> 8) & 0xf))) * 30)
- #define gdist(a, b) \
- ((ABS (((cusage[a].i >> 4) & 0xf) - ((cusage[b].i >> 4) & 0xf))) * 59)
- #define bdist(a, b) \
- ((ABS ((cusage[a].i & 0xf) - (cusage[b].i & 0xf))) * 11)
- #define mapx(x) (x + offsetx)
- #define mapy(y) (sh - (y) - 1 - offsety)
- #define fmapy(y) (y + offsety)
- #define inside(x, y) ((x) >= 0 && (y) >= 0 && (x) < sw && (y) < sh)
- #define EXACT(x) (x)
- #define RED(x) ((2 << 4) | x)
- #define GREEN(x) ((3 << 4) | x)
- #define BLUE(x) ((1 << 4) | x)
-
- static
- #ifdef __GNUC__
- __inline
- #endif
- long SQ(long x)
- {
- return x * x;
- }
-
- #define MAX_X 362
- #define MAX_Y_NTSC 241
- #define MAX_Y_PAL 283
-
- #ifdef LIBRARY_VERSION /* AmigaDOS 1.3 or earlier */
- #define BASENAME(x) (strrchr((x),'/') ? strrchr((x),'/')+1 : \
- (strrchr((x),':') ? strrchr((x),':')+1 : (x)))
- #else
- #define BASENAME(x) FilePart(x)
- #endif
-
- struct GfxBase *GfxBase = NULL;
- struct IntuitionBase *IntuitionBase = NULL;
- #ifndef NOIFFLIB
- struct Library *IFFBase = NULL;
- #endif
- struct Library *AslBase = NULL;
-
- static struct NewScreen screen = {
- 0, 0, 0, 0, 6, 0, 1, 0, AUTOSCROLL | CUSTOMSCREEN, NULL, "GetAmi", NULL, NULL
- };
-
- UWORD DriPens[] = { (UWORD)~0 };
-
- static struct TagItem ScreenTags[] = {
- #define DISPIDTAG 0
- {SA_DisplayID, NULL},
- {SA_Overscan, OSCAN_VIDEO},
- {SA_Pens, (ULONG)DriPens},
- {TAG_DONE, NULL}
- };
-
- static struct Image img = {
- 0, 0, 10, 10, 0, NULL, 0, 0, NULL
- };
-
- static struct Gadget CloseGadget = {
- NULL, 0, 0, 10, 10, GADGHCOMP | GADGIMAGE, RELVERIFY, BOOLGADGET, (APTR)&img,
- NULL, NULL, 0, NULL, 1, NULL
- };
-
- static struct NewWindow window = {
- 0, 0, 0, 0, 0, 1, GADGETUP | MENUPICK | MENUVERIFY,
- SMART_REFRESH | BACKDROP | BORDERLESS,
- &CloseGadget, NULL, NULL, NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN
- };
-
- struct TagItem FileReqTags[] = {
- #define WINTAG 0
- {ASLFR_Window, NULL},
- {ASLFR_SleepWindow, TRUE},
- {ASLFR_TitleText, (ULONG)"File name"},
- {ASLFR_DoSaveMode, TRUE},
- {ASLFR_RejectIcons, TRUE},
- {TAG_DONE, NULL}
- };
-
- static struct cuse {
- int i, j;
- } cusage[4096];
-
- static struct Window *w1 = NULL, *w2 = NULL, *w3 = NULL;
- static struct RastPort *rp1 = NULL, *rp2 = NULL, *rp3 = NULL;
- static struct Screen *s1 = NULL;
- static struct Screen *s2 = NULL;
- static struct Screen *s3 = NULL;
- static struct ViewPort *vp1 = NULL, *vp2 = NULL, *vp3 = NULL;
- static rle_pixel *sl[3];
- static rle_pixel **cmap;
- static unsigned int R[32], G[32], B[32];
- static char *tfile, *infile = NULL;
- static FILE *ifd = NULL, *tfd = NULL;
- static int width, height, depth, nused, sw, sh, sd, isham;
- #if 0
- static int nleft;
- #endif
- static int offsetx, offsety;
- static int bw=0, threescreens=0, havemenu=0, flip=0;
- static int forceham=0, haveoldpri=0;
- static long oldpri;
-
- static USHORT *Ptr = NULL;
-
- static USHORT RenderPtr[] = {
- 0x0000, 0x0000,
- 0x7800, 0x3800,
- 0x7000, 0x9000,
- 0x7800, 0x8800,
- 0x5C00, 0xA400,
- 0x0E00, 0x1200,
- 0x0700, 0x0900,
- 0xC300, 0xC400,
- 0xADD1, 0xADD1,
- 0xA955, 0xA955,
- 0xC9FF, 0xC9FF,
- 0x0000, 0x0000,
- 0x0BB8, 0x0BB8,
- 0x0AA8, 0x0AA8,
- 0x0AB8, 0x0AB8,
- 0x0008, 0x0008,
- 0x0038, 0x0038,
- 0x0000, 0x0000
- };
-
- extern char *mktemp(char *);
-
- UBYTE handleIDCMP (void);
-
- #define MENUITEMS 3
-
- static struct IntuiText txt[] = {
- { 0, 1, JAM1, 0, 0, NULL, "Save", NULL },
- { 0, 1, JAM1, 0, 0, NULL, "Save As", NULL },
- { 0, 1, JAM1, 0, 0, NULL, "Quit", NULL }
- };
-
- static struct MenuItem actions[] = {
- { &actions[1], 0, 0, 68, 8, ITEMTEXT | ITEMENABLED | HIGHBOX | COMMSEQ, 0,
- (APTR)&txt[0], NULL, 'S', NULL, MENUNULL
- },
- { &actions[2], 0, 10, 68, 8, ITEMTEXT | ITEMENABLED | HIGHBOX | COMMSEQ, 0,
- (APTR)&txt[1], NULL, 'A', NULL, MENUNULL
- },
- { NULL, 0, 20, 68, 8, ITEMTEXT | ITEMENABLED | HIGHBOX | COMMSEQ, 0,
- (APTR)&txt[2], NULL, 'Q', NULL, MENUNULL
- }
- };
-
- static struct Menu menu = {
- NULL, 10, 0, 64, 0, MENUENABLED, "Actions", &actions[0]
- };
-
- static char fnam[80] = {'\0'};
-
- int compare (struct cuse *, struct cuse *);
- int find_most_used (void);
- int display_rle (void);
- void show_rgb (void);
- void finish(void);
- void save(void);
- void FixColors(void);
- void ResetColors(void);
- void GetFile(void);
- int CalcWidth(int);
- int CalcHAMWidth(int);
- int CalcHeight(int, int);
- extern int IsPAL(void);
-
- #ifdef NOASM
- long curcol1, curcol2, curcol3;
-
- #define OptSetAPen1(rp, col) curcol1 = (col); if(curcol1) SetAPen((rp), curcol1)
- #define OptSetAPen2(rp, col) curcol2 = (col); if(curcol2) SetAPen((rp), curcol2)
- #define OptSetAPen3(rp, col) curcol3 = (col); if(curcol3) SetAPen((rp), curcol3)
-
- #define OptWritePixel1(rp, x, y) if(curcol1) WritePixel((rp), (x), (y))
- #define OptWritePixel2(rp, x, y) if(curcol2) WritePixel((rp), (x), (y))
- #define OptWritePixel3(rp, x, y) if(curcol3) WritePixel((rp), (x), (y))
- #endif
-
- int
- main(int argc, char **argv)
- {
- int i, SW=0, SH=0, dump=0, load=0;
- ULONG signalmask, signals;
- UBYTE done;
- BYTE pal;
- FILE *f;
- struct Preferences prefs;
- extern char *optarg;
- extern int optind;
-
- (void)signal(SIGINT, (void (*) (int))finish);
- while ((i = getopt(argc, argv, "w:h:o:dlb3fH")) != EOF) {
- switch(i) {
- case 'w':
- SW = atoi(optarg);
- break;
- case 'h':
- SH = atoi(optarg);
- break;
- case 'o':
- strcpy(fnam, optarg);
- break;
- case 'd':
- dump = 1;
- break;
- case 'l':
- load = 1;
- break;
- case 'b':
- bw = 1;
- forceham = 0;
- threescreens = 0;
- break;
- case '3':
- threescreens = 1;
- bw = 0;
- forceham = 0;
- break;
- case 'f':
- flip = 1;
- break;
- case 'H':
- forceham = 1;
- bw = 0;
- threescreens = 0;
- break;
- case '?':
- default:
- fprintf(stderr,
- "Usage: %s [-dlfb3H] [-w width] [-h height] [-o IFFfile] [file]\n",
- BASENAME(argv[0]));
- exit(1);
- }
- }
-
- if (optind >= argc)
- ifd = stdin;
- else{
- infile = argv[optind];
- if ((ifd = fopen (infile, "r")) == NULL)
- fprintf (stderr, "cannot open input file %s\n", infile), finish();
- }
-
- if ((tfile = mktemp ("t:rle.XXX")) == NULL)
- fprintf (stderr, "cannot create a temp name for tfile\n"), finish();
-
- if ((tfd = fopen (tfile, "w+")) == NULL)
- fprintf (stderr, "cannot open output file %s\n", tfile), finish();
-
- if ((GfxBase =
- (struct GfxBase *) OpenLibrary ("graphics.library", 0L)) == NULL)
- fprintf (stderr, "Can't open graphics.library\n"), finish();
-
- if ((IntuitionBase = (struct IntuitionBase *)
- OpenLibrary ("intuition.library", 0L)) == NULL)
- fprintf (stderr, "Can't open intuition.library\n"), finish();
-
- #ifndef NOIFFLIB
- if ((IFFBase = OpenLibrary(IFFNAME, IFFVERSION)) == NULL) {
- #endif
- actions[0].Flags &= ~ITEMENABLED;
- actions[1].Flags &= ~ITEMENABLED;
- #ifndef NOIFFLIB
- }
- #endif
- if ((AslBase = OpenLibrary("asl.library", 0L)) == NULL) {
- actions[1].Flags &= ~ITEMENABLED;
- }
-
- pal = IsPAL();
-
- if (find_most_used () == -1)
- fprintf (stderr, "error in find_most_used\n"), finish();
-
- if (load) {
- f = fopen("cmap", "r");
- if (!f) {
- fprintf(stderr, "Can't find cmap file\n");
- }else{
- fread((char *)R, sizeof(R), 1, f);
- fread((char *)G, sizeof(G), 1, f);
- fread((char *)B, sizeof(B), 1, f);
- }
- fclose(f);
- }
- if (dump) {
- f = fopen("cmap", "w");
- if (!f) {
- fprintf(stderr, "Can't create cmap file\n");
- }else{
- fwrite((char *)R, sizeof(R), 1, f);
- fwrite((char *)G, sizeof(G), 1, f);
- fwrite((char *)B, sizeof(B), 1, f);
- }
- fclose(f);
- }
- fseek (tfd, 0L, 0);
-
- if (!forceham && (bw || threescreens || nused <= 32)) {
- isham = FALSE;
- sw = CalcWidth(width);
- sh = CalcHeight(height, pal);
- if (nused > 16) sd = 5;
- else if (nused > 8) sd = 4;
- else if (nused > 4) sd = 3;
- else if (nused > 2) sd = 2;
- else if (nused > 0) sd = 1;
- else
- fprintf (stderr, "found 0!! colors\n"), finish();
- if (SW) sw = SW;
- if (SH) sh = SH;
- screen.Width = sw, screen.Height = sh, screen.Depth = sd;
- if (pal) {
- screen.ViewModes =
- ((sh > MAX_Y_PAL) ? LACE : 0) | ((sw > MAX_X) ? HIRES : 0);
- }else{
- screen.ViewModes =
- ((sh > MAX_Y_NTSC) ? LACE : 0) | ((sw > MAX_X) ? HIRES : 0);
- }
- window.Width = sw, window.Height = sh;
- } else {
- isham = TRUE;
- sd = 6;
- sw = CalcHAMWidth(width);
- sh = CalcHeight(height, pal);
- if (SW) sw = SW;
- if (SH) sh = SH;
- screen.Width = sw, screen.Height = sh, screen.Depth = sd;
- if (pal) {
- screen.ViewModes = ((sh > MAX_Y_PAL) ? LACE : 0) | HAM;
- }else{
- screen.ViewModes = ((sh > MAX_Y_NTSC) ? LACE : 0) | HAM;
- }
- window.Width = sw, window.Height = sh;
- }
- ScreenTags[DISPIDTAG].ti_Data = screen.ViewModes;
- if (pal) {
- ScreenTags[DISPIDTAG].ti_Data |= PAL_MONITOR_ID;
- }else{
- ScreenTags[DISPIDTAG].ti_Data |= NTSC_MONITOR_ID;
- }
-
- for (i=0; i<MENUITEMS; i++) {
- if (screen.ViewModes & HIRES) {
- actions[i].Width += COMMWIDTH;
- }else{
- actions[i].Width += LOWCOMMWIDTH;
- }
- }
-
- GetPrefs(&prefs, sizeof(prefs));
- Ptr = (USHORT *)AllocMem(POINTERSIZE * sizeof(USHORT), MEMF_CHIP);
- if (!Ptr) {
- fprintf (stderr, "Can't allocate chip memory for pointer\n");
- finish();
- }
-
- if (threescreens) {
- if ((s3 = OpenScreenTagList (&screen, ScreenTags)) == NULL)
- fprintf (stderr, "Can't open screen 3\n"), finish();
- ShowTitle (s3, FALSE);
- window.Screen = s3;
- if ((w3 = OpenWindow (&window)) == NULL)
- fprintf (stderr, "Can't open window 3\n"), finish();
- vp3 = &(s3->ViewPort);
- rp3 = w3->RPort;
- SetMenuStrip(w3, &menu);
-
- if ((s2 = OpenScreenTagList (&screen, ScreenTags)) == NULL)
- fprintf (stderr, "Can't open screen 2\n"), finish();
- ShowTitle (s2, FALSE);
- window.Screen = s2;
- if ((w2 = OpenWindow (&window)) == NULL)
- fprintf (stderr, "Can't open window 2\n"), finish();
- vp2 = &(s2->ViewPort);
- rp2 = w2->RPort;
- SetMenuStrip(w2, &menu);
- }
- if ((s1 = OpenScreenTagList (&screen, ScreenTags)) == NULL)
- fprintf (stderr, "Can't open screen 1\n"), finish();
- ShowTitle (s1, FALSE);
- window.Screen = s1;
- if ((w1 = OpenWindow (&window)) == NULL)
- fprintf (stderr, "Can't open window 1\n"), finish();
- vp1 = &(s1->ViewPort);
- rp1 = w1->RPort;
- SetMenuStrip(w1, &menu);
-
- if (isham) nused = 16;
- for (i = 0; i < nused; i++) {
- if (threescreens) {
- SetRGB4 (vp1, (long) i, (long) i, 0L, 0L);
- SetRGB4 (vp2, (long) i, 0L, (long) i, 0L);
- SetRGB4 (vp3, (long) i, 0L, 0L, (long) i);
- }else{
- SetRGB4 (vp1, (long) i, (long) R[i], (long) G[i], (long) B[i]);
- }
- }
-
- memcpy(Ptr, RenderPtr, POINTERSIZE * sizeof(USHORT));
- SetPointer(w1, Ptr, 16, 16, -1, 0);
- if (threescreens) {
- SetPointer(w2, Ptr, 16, 16, -1, 0);
- SetPointer(w3, Ptr, 16, 16, -1, 0);
- }
-
- display_rle ();
-
- memcpy(Ptr, prefs.PointerMatrix, POINTERSIZE * sizeof(USHORT));
- SetPointer(w1, Ptr, 16, 16, -1 + prefs.XOffset, prefs.YOffset);
- if (threescreens) {
- SetPointer(w2, Ptr, 16, 16, -1 + prefs.XOffset, prefs.YOffset);
- SetPointer(w3, Ptr, 16, 16, -1 + prefs.XOffset, prefs.YOffset);
- }
-
- if (fnam[0]) {
- #ifndef NOIFFLIB
- if (IFFBase) save();
- #else
- save();
- #endif
- }else{
- done = (UBYTE)0;
- if (threescreens) {
- signalmask = (1L << w1->UserPort->mp_SigBit) |
- (1L << w2->UserPort->mp_SigBit) |
- (1L << w3->UserPort->mp_SigBit);
- }else{
- signalmask = 1L << w1->UserPort->mp_SigBit;
- }
-
- if (threescreens) { /* Run at high priority to reduce flicker */
- haveoldpri = 1;
- oldpri = SetTaskPri(FindTask(0L), 19L);
- }
- while (!done) {
- if (threescreens) {
- if (!havemenu) {
- ScreenToFront(s1);
- }
- done = handleIDCMP();
- if (!havemenu) {
- ScreenToFront(s2);
- }
- done |= handleIDCMP();
- if (!havemenu) {
- ScreenToFront(s3);
- }
- done |= handleIDCMP();
- }
- if (!threescreens || havemenu) {
- signals = Wait(signalmask);
- if (signals & signalmask) {
- done = handleIDCMP();
- }
- }
- }
- }
- finish();
- #ifdef __SASC
- return 0;
- #endif
- }
-
- int
- compare (struct cuse *a, struct cuse *b)
- {
- if (a->j < b->j)
- return 1;
- else if (a->j > b->j)
- return -1;
- else
- return 0;
- }
-
- int
- find_most_used (void)
- {
- rle_hdr rle_f_hdr;
- char comi[4][100];
- char *como;
- unsigned char r, g, b;
- int ncolors, i, j, x, packed, pix, col;
-
- rle_f_hdr.rle_file = ifd;
- if (rle_get_setup(&rle_f_hdr) < 0)
- return -1;
-
- RLE_CLR_BIT (rle_f_hdr, RLE_ALPHA);
- for (i = 3; i < rle_f_hdr.ncolors; i++)
- RLE_CLR_BIT (rle_f_hdr, i);
-
- ncolors = rle_f_hdr.ncolors > 3 ? 3 : rle_f_hdr.ncolors;
- if (ncolors == 2)
- return -1;
-
- height = rle_f_hdr.ymax - rle_f_hdr.ymin + 1;
- width = rle_f_hdr.xmax - rle_f_hdr.xmin + 1;
-
- depth = 0, packed = 0;
- if ((como = rle_getcom ("cy_depth", &rle_f_hdr)) != NULL) {
- depth = atoi (como);
- if ((como = rle_getcom ("cy_width", &rle_f_hdr)) != NULL)
- width = atoi (como);
- como = rle_getcom ("cy_packed", &rle_f_hdr);
- packed = como ? 1 : 0;
- }
- if (!depth)
- depth = ncolors * 8;
-
- for (i = 0; i < 3; i++)
- if ((sl[i] = (rle_pixel *) malloc(rle_f_hdr.xmax -
- rle_f_hdr.xmin + 1)) == NULL) {
- for (j = 0; j < i; j++)
- free ((char *) sl[j]);
- return -1;
- }
-
- rle_f_hdr.xmax -= rle_f_hdr.xmin, rle_f_hdr.xmin = 0;
-
- rle_dflt_hdr.dispatch = RUN_DISPATCH;
- rle_dflt_hdr.alpha = 0;
- rle_dflt_hdr.background = rle_f_hdr.background;
- rle_dflt_hdr.ncmap = rle_f_hdr.ncmap;
- rle_dflt_hdr.cmaplen = rle_f_hdr.cmaplen;
- rle_dflt_hdr.cmap = rle_f_hdr.cmap;
- rle_dflt_hdr.comments = NULL;
- rle_dflt_hdr.rle_file = tfd;
- rle_dflt_hdr.xmin = 0;
- rle_dflt_hdr.xmax = width - 1;
- rle_dflt_hdr.ymin = 0;
- rle_dflt_hdr.ymax = height - 1;
- rle_dflt_hdr.ncolors = ncolors;
- for (i = 0; i < MIN (3, ncolors); i++)
- RLE_SET_BIT (rle_dflt_hdr, i);
- for (i = MIN (3, ncolors); i < ncolors; i++)
- RLE_CLR_BIT (rle_dflt_hdr, i);
- RLE_CLR_BIT (rle_dflt_hdr, RLE_ALPHA);
-
- if (packed) {
- sprintf (comi[0], "cy_depth=%d", depth), rle_putcom (comi[0], &rle_dflt_hdr);
- sprintf (comi[1], "cy_width=%d", width), rle_putcom (comi[1], &rle_dflt_hdr);
- strcpy (comi[2], "cy_packed=1"), rle_putcom (comi[2], &rle_dflt_hdr);
- }
-
- cmap = buildmap (&rle_f_hdr, 3, 1.0, 0.0);
-
- rle_put_setup (&rle_dflt_hdr);
-
- while (rle_getrow(&rle_f_hdr, sl) <= rle_f_hdr.ymax) {
- rle_putrow (sl, width, &rle_dflt_hdr);
- if (ncolors == 3) {
- for (x = 0; x < width; x++)
- r = sl[0][x], g = sl[1][x], b = sl[2][x], cusage[cindex(r, g, b)].j++;
- } else if (ncolors == 1 && !packed) {
- for (x = 0; x < width; x++) {
- r = cmap[0][sl[0][x]];
- g = cmap[1][sl[0][x]];
- b = cmap[2][sl[0][x]];
- cusage[cindex(r, g, b)].j++;
- }
- } else {
- for (col = 0, x = 0; x < width; col = (col + 1) & 7, x++) {
- pix = (sl[0][x / 8] & (1 << (7 - col))) ? 0: 255;
- r = pix, g = pix, b = pix, cusage[cindex(r, g, b)].j++;
- }
- }
- }
- for (i = 0; i < 3; i++)
- free((char *) sl[i]);
-
- nused = 0;
- for (i = 0; i < 4096; i++) {
- cusage[i].i = i;
- if (cusage[i].j)
- nused++;
- }
- printf ("colors used: %d\n", nused);
-
- qsort ((char *) cusage, 4096, sizeof (struct cuse), compare);
-
- if (threescreens) {
- nused = 16;
- return 0;
- }
- if (bw) {
- for (i = 0; i < 16; i++) {
- R[i] = G[i] = B[i] = i;
- nused = 16;
- }
- return 0;
- }
- if (nused <= 32) {
- for (i = 0; i < 32; i++) {
- R[i] = (cusage[i].i >> 8) & 0xf;
- G[i] = (cusage[i].i >> 4) & 0xf;
- B[i] = cusage[i].i & 0xf;
- }
- return 0;
- }
-
- #if 0
- nleft = nused;
- for (i = nused - 1; i >= 0; i--) {
- if (nleft <= 16)
- break;
- for (j = 0; j < i; j++)
- if (rdist (i, j) + gdist (i, j) + bdist (i, j) <= 1) {
- cusage[i].j = 0, nleft--;
- break;
- }
- }
- printf ("colors left %d\n", nleft);
- #endif
-
- for (i = 0, j = 0; j < 16 && i < nused; i++)
- if (cusage[i].j) {
- R[j] = (cusage[i].i >> 8) & 0xf;
- G[j] = (cusage[i].i >> 4) & 0xf;
- B[j] = cusage[i].i & 0xf;
- j++;
- }
-
- return 0;
- }
-
- static int x, y;
- static unsigned char r, g, b;
-
- int
- display_rle (void)
- {
- rle_hdr rle_f_hdr;
- char *como;
- int ncolors, i, j, packed, pix, col;
-
- rle_f_hdr.rle_file = tfd;
- if (rle_get_setup(&rle_f_hdr) < 0)
- return -1;
-
- RLE_CLR_BIT (rle_f_hdr, RLE_ALPHA);
- for (i = 3; i < rle_f_hdr.ncolors; i++)
- RLE_CLR_BIT (rle_f_hdr, i);
-
- ncolors = rle_f_hdr.ncolors > 3 ? 3 : rle_f_hdr.ncolors;
- if (ncolors == 2)
- return -1;
-
- height = rle_f_hdr.ymax - rle_f_hdr.ymin + 1;
- width = rle_f_hdr.xmax - rle_f_hdr.xmin + 1;
-
- depth = 0, packed = 0;
- if ((como = rle_getcom ("cy_depth", &rle_f_hdr)) != NULL) {
- depth = atoi (como);
- if ((como = rle_getcom ("cy_width", &rle_f_hdr)) != NULL)
- width = atoi (como);
- como = rle_getcom ("cy_packed", &rle_f_hdr);
- packed = como ? 1 : 0;
- }
- if (!depth)
- depth = ncolors * 8;
- offsetx = (sw - width) / 2;
- offsety = (sh - height) / 2;
-
- for (i = 0; i < 3; i++)
- if ((sl[i] = (rle_pixel *) malloc(rle_f_hdr.xmax -
- rle_f_hdr.xmin + 1)) == NULL) {
- for (j = 0; j < i; j++)
- free ((char *) sl[j]);
- return -1;
- }
-
- rle_f_hdr.xmax -= rle_f_hdr.xmin, rle_f_hdr.xmin = 0;
-
- while ((y = rle_getrow(&rle_f_hdr, sl)) <= rle_f_hdr.ymax) {
- if (handleIDCMP()) {
- finish();
- }
- y -= rle_f_hdr.ymin;
- if (ncolors == 3) {
- for (x = 0; x < width; x++)
- r = sl[0][x], g = sl[1][x], b = sl[2][x], show_rgb ();
- } else if (ncolors == 1 && !packed) {
- for (x = 0; x < width; x++) {
- r = cmap[0][sl[0][x]];
- g = cmap[1][sl[0][x]];
- b = cmap[2][sl[0][x]];
- show_rgb ();
- }
- } else {
- for (col = 0, x = 0; x < width; col = (col + 1) & 7, x++) {
- pix = (sl[0][x / 8] & (1 << (7 - col))) ? 0: 255;
- r = pix, g = pix, b = pix, show_rgb ();
- }
- }
- }
- for (i = 0; i < 3; i++)
- free((char *) sl[i]);
-
- return 0;
- }
-
- void
- show_rgb (void)
- {
- int xx, yy, i, j, color;
- long d, td, d1, d2, d3, rd, gd, bd;
-
- static unsigned char pr, pg, pb;
-
- xx = mapx (x);
- if (!flip) {
- yy = mapy (y);
- }else{
- yy = fmapy (y);
- }
- if (!inside (xx, yy)){
- return;
- }
-
- if (bw) {
- #if 0
- r = g = b = 0.35 * r + 0.55 * g + 0.10 * b;
- #else
- r = g = b = (35 * r + 55 * g + 10 * b) / 100;
- #endif
- }
- #ifndef AZTEC_C
- r >>= 4, g >>= 4, b >>= 4;
- #else /* avoid a manx bug */
- r = (r >> 4) & 0xf, g = (g >> 4) & 0xf, b = (b >> 4) & 0xf;
- #endif
- if (threescreens) {
- #ifdef NOASM
- OptSetAPen1 (rp1, (long) r); OptWritePixel1 (rp1, (long) xx, (long) yy);
- OptSetAPen2 (rp2, (long) g); OptWritePixel2 (rp2, (long) xx, (long) yy);
- OptSetAPen3 (rp3, (long) b); OptWritePixel3 (rp3, (long) xx, (long) yy);
- #else
- MultiPlot(w1, xx, yy, r);
- MultiPlot(w2, xx, yy, g);
- MultiPlot(w3, xx, yy, b);
- #endif
- return;
- }
- if (!isham) {
- for (i = 0; i < nused; i++) {
- if (R[i] == (int) r && G[i] == (int) g && B[i] == (int) b) {
- #ifdef NOASM
- OptSetAPen1 (rp1, (long) i); OptWritePixel1 (rp1, (long) xx, (long) yy);
- #else
- MultiPlot(w1, xx, yy, i);
- #endif
- break;
- }
- }
- return;
- }
- for (i = 0, d = MAXINT, j = -1; i < 16; i++) {
- td = SQ ((long)r - (long)R[i]) +
- SQ ((long)g - (long)G[i]) +
- SQ ((long)b - (long)B[i]);
- if (td < d)
- d = td, j = i;
- if (d == 0)
- break;
- }
- if (d == 0 || x == 0) {
- #ifdef NOASM
- OptSetAPen1 (rp1, (long) EXACT (j));
- #else
- color = EXACT(j);
- #endif
- pr = R[j], pg = G[j], pb = B[j];
- } else {
- rd = SQ ((long)r - (long)pr);
- gd = SQ ((long)g - (long)pg);
- bd = SQ ((long)b - (long)pb);
- d1 = rd + gd, d2 = rd + bd, d3 = gd + bd;
- if (d <= d1 && d <= d2 && d <= d3) {
- #ifdef NOASM
- OptSetAPen1 (rp1, (long) EXACT (j));
- #else
- color = EXACT(j);
- #endif
- pr = R[j], pg = G[j], pb = B[j];
- } else if (d1 <= d2 && d1 <= d3) {
- #ifdef NOASM
- OptSetAPen1 (rp1, (long) BLUE (b));
- #else
- color = BLUE(b);
- #endif
- pb = b;
- } else if (d2 <= d3 && d2 <= d1) {
- #ifdef NOASM
- OptSetAPen1 (rp1, (long) GREEN (g));
- #else
- color = GREEN(g);
- #endif
- pg = g;
- } else {
- #ifdef NOASM
- OptSetAPen1 (rp1, (long) RED (r));
- #else
- color = RED(r);
- #endif
- pr = r;
- }
- }
- #ifdef NOASM
- OptWritePixel1 (rp1, (long) xx, (long) yy);
- #else
- MultiPlot(w1, xx, yy, color);
- #endif
- }
-
- void
- finish(void)
- {
- if (haveoldpri) {
- SetTaskPri(FindTask(0L), oldpri);
- }
-
- if (ifd && ifd != stdin)
- fclose (ifd);
-
- if (tfd) {
- fclose (tfd);
- unlink (tfile);
- }
-
- if (w1) {
- if (w1->MenuStrip)
- ClearMenuStrip(w1);
- CloseWindow (w1);
- }
-
- if (w2) {
- if (w2->MenuStrip)
- ClearMenuStrip(w2);
- CloseWindow (w2);
- }
-
- if (w3) {
- if (w3->MenuStrip)
- ClearMenuStrip(w3);
- CloseWindow (w3);
- }
-
- if (s1)
- CloseScreen (s1);
-
- if (s2)
- CloseScreen (s2);
-
- if (s3)
- CloseScreen (s3);
-
- if (Ptr)
- FreeMem(Ptr, POINTERSIZE * sizeof(USHORT));
-
- if (GfxBase)
- CloseLibrary ((struct Library *)GfxBase);
-
- if (IntuitionBase)
- CloseLibrary ((struct Library *)IntuitionBase);
-
- #ifndef NOIFFLIB
- if (IFFBase)
- CloseLibrary (IFFBase);
- #endif
-
- if (AslBase)
- CloseLibrary(AslBase);
-
- exit (0);
- }
-
- UBYTE
- handleIDCMP(void)
- {
- UBYTE flag = 0;
- struct IntuiMessage *message;
- USHORT code, selection;
- ULONG class, itemnum;
- int t;
-
- while ((message = (struct IntuiMessage *)GetMsg(w1->UserPort)) ||
- (threescreens && (message=(struct IntuiMessage *)GetMsg(w2->UserPort))) ||
- (threescreens && (message=(struct IntuiMessage *)GetMsg(w3->UserPort)))) {
- class = message->Class;
- code = message->Code;
- switch (class) {
- case GADGETUP:
- flag = 1;
- break;
- case MENUVERIFY:
- havemenu = 1;
- FixColors();
- break;
- case MENUPICK:
- selection = code;
- while (selection != MENUNULL) {
- itemnum = ITEMNUM(selection);
- switch (itemnum) {
- case 0:
- if (ifd == stdin) {
- if (threescreens) ScreenToFront(s1);
- GetFile();
- }else{
- strcpy(fnam, infile);
- t = strlen(fnam);
- if ( (t >= 4) && (strcmp(&fnam[t-4], ".rle") == 0)) {
- fnam[t-4] = '\000';
- }
- strcat(fnam, ".ilbm");
- }
- save();
- break;
- case 1:
- if (threescreens) ScreenToFront(s1);
- GetFile();
- save();
- break;
- case 2:
- flag = 1;
- break;
- default:
- break;
- }
- selection = ((struct MenuItem *)ItemAddress
- (&menu, (LONG)selection))->NextSelect;
- }
- havemenu = 0;
- ResetColors();
- break;
- default:
- break;
- }
- ReplyMsg((struct Message *)message);
- }
- return flag;
- }
-
- void
- save(void)
- {
- #ifndef NOIFFLIB
- char *name;
-
- if (*fnam == '\000')
- return;
-
- if (IFFBase) {
- ResetColors();
- if (threescreens) {
- name = malloc(strlen(fnam) + 4);
- if (!name) {
- fprintf(stderr, "malloc failed\n");
- return;
- }
- strcpy(name, fnam);
- strcat(name, ".r");
- IFFL_SaveBitMap
- (name, &(s1->BitMap),vp1->ColorMap->ColorTable,(isham ? 0x81 : 1));
- strcpy(name, fnam);
- strcat(name, ".g");
- IFFL_SaveBitMap
- (name, &(s2->BitMap),vp2->ColorMap->ColorTable,(isham ? 0x81 : 1));
- strcpy(name, fnam);
- strcat(name, ".b");
- IFFL_SaveBitMap
- (name, &(s3->BitMap),vp3->ColorMap->ColorTable,(isham ? 0x81 : 1));
- free(name);
- }else{
- IFFL_SaveBitMap
- (fnam, &(s1->BitMap),vp1->ColorMap->ColorTable,(isham ? 0x81 : 1));
- }
- FixColors();
- }
- #endif
- }
-
- void
- SetColor(long n, long c)
- {
- long r, g, b;
-
- r = (c >> 8) & 0xf;
- g = (c >> 4) & 0xf;
- b = c & 0xf;
- SetRGB4(vp1, n, r, g, b);
- if (threescreens) {
- SetRGB4(vp2, n, r, g, b);
- SetRGB4(vp3, n, r, g, b);
- }
- }
-
- void
- FixColors(void)
- {
- struct Preferences prefs;
-
- GetPrefs(&prefs, sizeof(prefs));
- if (threescreens) {
- #ifdef NOASM
- OptSetAPen1(rp1, 1L); OptSetAPen2(rp2, 1L); OptSetAPen3(rp3, 1L);
- #else
- SetAPen(rp1, 1L); SetAPen(rp2, 1L); SetAPen(rp3, 1L);
- #endif
- SetBPen(rp1, 0L); SetBPen(rp2, 0L); SetBPen(rp3, 0L);
- }else{
- #ifdef NOASM
- OptSetAPen1(rp1, 1L);
- #else
- SetAPen(rp1, 1L);
- #endif
- SetBPen(rp1, 0L);
- }
- SetColor(0L, (long)prefs.color0);
- SetColor(1L, (long)prefs.color1);
- SetColor(2L, (long)prefs.color2);
- SetColor(3L, (long)prefs.color3);
- }
-
- void
- ResetColors(void)
- {
- long i;
-
- for (i=0; i<4; i++) {
- if (threescreens) {
- SetRGB4 (vp1, i, i, 0L, 0L);
- SetRGB4 (vp2, i, 0L, i, 0L);
- SetRGB4 (vp3, i, 0L, 0L, i);
- }else{
- SetRGB4 (vp1, (long) i, (long) R[i], (long) G[i], (long) B[i]);
- }
- }
- }
-
- int
- CalcWidth(int width)
- {
- if (width <= 320) return 320;
- if (width <= MAX_X) return width;
- if (width <= 640) return 640;
- return width;
- }
-
- int
- CalcHAMWidth(int width)
- {
- if (width <= 320) return 320;
- return width;
- }
-
- int
- CalcHeight(int height, int pal)
- {
- if (pal) {
- if (height <= 256) return 256;
- if (height <= MAX_Y_PAL) return height;
- if (height <= 512) return 512;
- return height;
- }else{
- if (height <= 200) return 200;
- if (height <= MAX_Y_NTSC) return height;
- if (height <= 400) return 400;
- return height;
- }
- }
-
- void
- GetFile(void)
- {
- struct FileRequester *freq;
- int tmp;
-
- FileReqTags[WINTAG].ti_Data = (ULONG)w1;
- freq = AllocAslRequest(ASL_FileRequest, FileReqTags);
- if (!freq){
- fprintf(stderr, "Can't allocate file requester\n");
- return;
- }
- FixColors();
- tmp = AslRequest(freq, NULL);
- ResetColors();
- fnam[0] = '\000';
- if (tmp && freq->fr_File[0]) {
- strcpy(fnam, freq->fr_Drawer);
- tmp = strlen(fnam) - 1;
- if (tmp >= 0 && fnam[tmp] != '/' && fnam[tmp] != ':'){
- strcat(fnam, "/");
- }
- strcat (fnam, freq->fr_File);
- }
- FreeAslRequest(freq);
- return;
- }
-
- /*
- No-one in his right mind would want to run this program from the Workbench!
- */
- #ifndef __SASC
- #ifndef __GNUC__
- void
- _wb_parse(void)
- {}
- #endif
- #endif
-